
enum STATUS {
    InvalidTouch,
    LongTouch,
    ShortTouch,
    TouchMove,
    TouchEnd,
}
const AlOff = 10;//保持长按所允许的滑动偏移值
const ShortLongBorderTime = 0.2;//从点击到长按状态所需的时间
const MaxTouchEndTime = 0.2;//响应长按操作所需的时间
const { ccclass, property } = cc._decorator;

@ccclass
export default class LongTouch extends cc.Component {

    @property(cc.Component.EventHandler)
    longTouchFunc: cc.Component.EventHandler[] = [];
    @property(cc.Component.EventHandler)
    shortTouchFunc: cc.Component.EventHandler[] = [];

    @property(cc.Component.EventHandler)
    touchStartFunc: cc.Component.EventHandler[] = [];
    @property(cc.Component.EventHandler)
    touchMoveFunc: cc.Component.EventHandler[] = [];
    @property(cc.Component.EventHandler)
    touchEndFunc: cc.Component.EventHandler[] = [];
    @property(cc.Component.EventHandler)
    touchCancelFunc: cc.Component.EventHandler[] = [];

    // LIFE-CYCLE CALLBACKS:
    private bPos: cc.Vec2 = null;
    private ePos: cc.Vec2 = null;
    private status: number = null;
    private touchStartTime: number = null;
    private touchEndTime: number = null;
    private doing: boolean = false;

     onLoad () {
         console.log("yyy111y")
     }

    onEnable() {
        this.node.on(cc.Node.EventType.TOUCH_START, this.TouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.TouchMove, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.TouchEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.TouchCancel, this);
    }
    onDisable() {
        this.node.off(cc.Node.EventType.TOUCH_START, this.TouchMove, this);
        this.node.off(cc.Node.EventType.TOUCH_MOVE, this.TouchMove, this);
        this.node.off(cc.Node.EventType.TOUCH_END, this.TouchEnd, this);
        this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.TouchCancel, this);
    }

    start() {

    }

    // update (dt) {}
    private IsTouchMove() {
        let off = this.ePos.sub(this.bPos).mag();
        return off > AlOff;
    }
    private UpdateStatus() {
        this.touchEndTime = new Date().getTime();
        let timeS = this.touchEndTime - this.touchStartTime;
        timeS /= 1e3;
        let b = !this.IsTouchMove();
        if (timeS < ShortLongBorderTime) {
            b ? this.status = STATUS.ShortTouch : this.status = STATUS.TouchMove;
        }
        else if (timeS < MaxTouchEndTime) {
            b ? this.status = STATUS.InvalidTouch : this.status = STATUS.TouchMove;
        }
        else {
            b ? this.status = STATUS.LongTouch : this.status = STATUS.TouchMove;
        }
    }
    private DoWithStatus() {
        this.UpdateStatus();
        if (this.doing || this.status == STATUS.TouchEnd) return;
        this.doing = true;
        switch (this.status) {
            case STATUS.ShortTouch: {
                this.shortTouchFunc && cc.Component.EventHandler.emitEvents(this.shortTouchFunc);
            } break;
            case STATUS.LongTouch: {
                this.longTouchFunc && cc.Component.EventHandler.emitEvents(this.longTouchFunc);
            } break;
            case STATUS.TouchMove: { } break;
        }
    }
    TouchStart(evt: cc.Touch) {
        let bPos = evt.getLocation();
        this.bPos = bPos.add(cc.v2());
        this.ePos = bPos.add(cc.v2());
        this.status = STATUS.LongTouch;
        this.touchStartTime = new Date().getTime();
        this.doing = false;
        this.unscheduleAllCallbacks();
        this.scheduleOnce(this.DoWithStatus.bind(this), MaxTouchEndTime);
        this.touchStartFunc && cc.Component.EventHandler.emitEvents(this.touchStartFunc, bPos);
    }
    TouchMove(evt: cc.Touch) {
        let dtPos = evt.getDelta();
        this.ePos.addSelf(dtPos);
        this.UpdateStatus();
        this.IsTouchMove() && this.touchMoveFunc && cc.Component.EventHandler.emitEvents(this.touchMoveFunc, dtPos);
    }
    TouchEnd(evt: cc.Touch) {
        this.unscheduleAllCallbacks();
        this.DoWithStatus();
        this.doing = true;
        this.status = STATUS.TouchEnd;
        this.touchEndFunc && cc.Component.EventHandler.emitEvents(this.touchEndFunc, this.ePos);
    }
    TouchCancel() {
        this.unscheduleAllCallbacks();
        this.status = STATUS.TouchEnd;
        this.touchCancelFunc && cc.Component.EventHandler.emitEvents(this.touchCancelFunc, this.ePos);
    }
}
